import java.util.LinkedList;

/**
 * Queue blocks when client tries to enqueue to the full queue and dequeue from
 * the empty queue.
 * 
 * @author ruinvepc
 * 
 * @param <T>
 */
public class BlockingQueue<T> {

    private LinkedList<T> queue;
    private int limit;

    public BlockingQueue(int limit) {
        this.limit = limit;
        queue = new LinkedList<T>();
    }

    public synchronized void enqueue(T item) throws InterruptedException {
        if (queue.size() == limit) {
            System.out.println("queue is full");
            wait();
        }
        if (queue.size() == 0) {
            notifyAll();
        }
        queue.addFirst(item);
    }

    public synchronized T dequeue() throws InterruptedException {
        if (queue.size() == 0) {
            wait();
        }
        if (queue.size() == limit) {
            notifyAll();
        }
        return queue.removeLast();
    }

}
